﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using NHibernate;
using NHibernate.Criterion;
using Rodunu.Movies.Contracts;
using Rodunu.Movies.Interfaces.Data;
using Rodunu.Utilities.Reflection;

namespace Rodunu.Movies.Data
{
    public class Repository<T> : IRepository<T> where T : IIdentifier
    {
        private static ISession _Session;

        #region Implementation of IRepository<T>

        public virtual void Create(T identifiable)
        {
            _Session = DBHelper.GetCurrentSession();
            ITransaction transaction = _Session.BeginTransaction();
            _Session.Save(identifiable);
            transaction.Commit();
            DBHelper.CloseSession();
        }

        public virtual T Find(long id)
        {
            _Session = DBHelper.GetCurrentSession();
            return (T)_Session.Load(typeof(T), id);
        }

        //public IList<T> FindByBase(IIdentifier identifiable)
        //{
        //    //TODO: set this up for more custom dev
        //    return
        //        DBHelper.GetCurrentSession().CreateCriteria(typeof(T)).Add(Restrictions.Eq("ServerDetail", identifiable)).List
        //            <T>();
        //}

        public IList<T> FindByBase(T identifiable)
        {
            return
                DBHelper.GetCurrentSession().CreateCriteria(typeof (T)).Add(
                    Restrictions.Eq(identifiable.GetType().Name, identifiable)).List<T>();
        }

        public IList<T> FindByBase(string propertyName, object propertyValue)
        {
            return
                DBHelper.GetCurrentSession().CreateCriteria(typeof(T)).Add(
                    Restrictions.Eq(propertyName, propertyValue)).List<T>();
        }

        public T FindByBaseUnique(T identifiable)
        {
            return
                DBHelper.GetCurrentSession().CreateCriteria(typeof(T)).Add(
                    Restrictions.Eq(identifiable.GetType().Name, identifiable)).UniqueResult<T>();
        }

        public T FindByBaseUnique(string propertyName, object propertyValue)
        {
            return
                DBHelper.GetCurrentSession().CreateCriteria(typeof (T)).Add(
                    Restrictions.Eq(propertyName, propertyValue)).UniqueResult<T>();
        }

        public IList<T> FindAll()
        {
            return DBHelper.GetCurrentSession().CreateCriteria(typeof(T)).List<T>();
        }

        public void Delete(T identifiable)
        {
            _Session = DBHelper.GetCurrentSession();
            ITransaction transaction = _Session.BeginTransaction();
            _Session.Delete(identifiable);
            transaction.Commit();
            DBHelper.CloseSession();
        }

        public virtual void Update(T identifiable)
        {
            _Session = DBHelper.GetCurrentSession();
            ITransaction transaction = _Session.BeginTransaction();
            _Session.Update(identifiable);
            transaction.Commit();
            DBHelper.CloseSession();
        }

        #endregion
    }
}
